package br.com.ordersys.framework.restlayer;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.context.ApplicationContext;

import br.com.ordersys.framework.restlayer.auth.AuthenticationData;
import br.com.ordersys.framework.utils.StringUtils;

public class RestCallContext {
	private static ThreadLocal<RestCallContext> current = new ThreadLocal<RestCallContext>();

	private Object inputObject;
	private String serviceName;
	private String moduleName;
	private List<String> resultWarnings;
	private AuthenticationData authenticationData;

	private ServletContext servletContext;
	private HttpSession httpSession;
	private ApplicationContext springContext;
	private HttpServletRequest request;
	private String tenantID;
	private AsyncCallInfo asyncCallInfo;
	private Locale currentUserLocale;

	public Object getInputObject() {
		return inputObject;
	}

	public void setInputObject(Object inputObject) {
		this.inputObject = inputObject;
	}

	public void registry() {
		current.set(this);
	}

	public static void unregistry() {
		current.remove();
	}

	public String getServiceName() {
		return serviceName;
	}

	public void setServiceName(String serviceName) {
		this.serviceName = serviceName;
	}

	public String getModuleName() {
		return moduleName;
	}

	public void setModuleName(String moduleName) {
		this.moduleName = moduleName;
	}

	public static RestCallContext get() {
		return current.get();
	}

	public void addResultWarning(String warning) {
		warning = StringUtils.emptyAsNull(warning);

		if (warning != null) {
			if (resultWarnings == null) {
				resultWarnings = new ArrayList<String>();
			}

			resultWarnings.add(warning);
		}
	}

	public List<String> getResultWarnings() {
		return resultWarnings;
	}

	public static void cancelThisCall() throws CallCanceledException {
		throw new CallCanceledException();
	}

	public AuthenticationData getAuthenticationData() {
		return authenticationData;
	}

	void setAuthenticationData(AuthenticationData authenticationData) {
		this.authenticationData = authenticationData;
	}

	public ServletContext getServletContext() {
		return servletContext;
	}

	void setServletContext(ServletContext servletContext) {
		this.servletContext = servletContext;
	}

	public HttpSession getHttpSession() {
		return httpSession;
	}

	void setHttpSession(HttpSession httpSession) {
		this.httpSession = httpSession;
	}

	public ApplicationContext getSpringContext() {
		return springContext;
	}

	void setSpringContext(ApplicationContext springContext) {
		this.springContext = springContext;
	}

	public HttpServletRequest getRequest() {
		return request;
	}

	void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	public String getTenantID() {
		return tenantID;
	}

	void setTenantID(String tenantID) {
		this.tenantID = tenantID;
	}

	public static class AsyncCallInfo {
		private volatile boolean isCanceled;
		private Object statusDetail;
		private String asynCallID;

		public boolean isCanceled() {
			return isCanceled;
		}

		public void setCanceled(boolean isCanceled) {
			this.isCanceled = isCanceled;
		}

		public Object getStatusDetail() {
			return statusDetail;
		}

		public void setStatusDetail(Object statusDetail) {
			this.statusDetail = statusDetail;
		}

		public String getAsynCallID() {
			return asynCallID;
		}

		public void setAsynCallID(String asynCallID) {
			this.asynCallID = asynCallID;
		}
	}

	public static ThreadLocal<RestCallContext> getCurrent() {
		return current;
	}

	public AsyncCallInfo getAsyncCallInfo() {
		return asyncCallInfo;
	}

	public void setAsyncCallInfo(AsyncCallInfo asyncCallInfo) {
		this.asyncCallInfo = asyncCallInfo;
	}

	public Locale getCurrentUserLocale() {
		return currentUserLocale;
	}

	public void setCurrentUserLocale(Locale currentUserLocale) {
		this.currentUserLocale = currentUserLocale;
	}
}
